﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using LogLib;
using Microsoft.VisualBasic.Devices;

namespace ComLib.ComFun
{
    public class ProcessInfoStatistics
    {
        private bool _bExit = false;          //退出

        private Process _process = null;

        /// <summary>
        /// 预受理进程对象
        /// </summary>
        private Process _emperor = null;

        private string _strProcessName;

        private Thread _thread;

        private bool _withYSL = false;
        public bool WithYSL
        {
            get { return _withYSL; }
            set { _withYSL = value; }
        }

        public ProcessInfoStatistics(string name)
        {
            _strProcessName = name;
        }

        public ProcessInfoStatistics()
        {
            _process = Process.GetCurrentProcess();
            _strProcessName = _process.ProcessName;
        }

        private void ThreadFun()
        {
            Log.AddBeginningBoundary();
            Log.WriteAsync("应用程序名称: " + _strProcessName);
            Log.WriteAsync("ThreadFun Start...");
            try
            {               
                while (!_bExit)
                {
                    if (!IsProcessExists())
                    {
                        Log.WriteAsync("未找到指定的进程，统计意外结束...");
                        break;
                    }
                    QueryAndRecordStatus("SPC", _process);
                    if (_withYSL)
                    {
                        if (IsEmperorExists())
                        {
                            QueryAndRecordStatus("Emperor", _emperor);
                        }
                    }
                    Thread.Sleep(5000);
                }               
            }
            catch (ThreadAbortException ex)
            {
                Log.WriteAsync(ex.Message);
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
            finally
            {
                Log.WriteAsync("ThreadFun End...");
                Log.AddEndingBoundary();
            }
        }

        /// <summary>
        /// 监控拍照程序状态
        /// </summary>
        /// <param name="prc">拍照程序进程对象</param>
        /// <returns>0：拍照程序正常；1：需要重启拍照程序</returns>
        private void QueryAndRecordStatus(string procName, Process p)
        {
            try
            {
                // 获取程序内存大小
                int nPrivateMemorySize = (int)(p.WorkingSet64 / 1024L / 1024L);
                // 获取句柄数量
                int nHandleCount = p.HandleCount;
                // 获取GDI数量
                int nGDICount = WinAPI.GetGuiResourcesGDICount(p);
                ComputerInfo ci = new ComputerInfo();
                string strLog = string.Format("{0}: 内存占用:{1}MB; 句柄数量:{2}; GDI对象:{3}, 可用内存大小{4}MB", 
                    procName, 
                    nPrivateMemorySize, 
                    nHandleCount, 
                    nGDICount,
                    ci.AvailablePhysicalMemory / 1024 / 1024);
                Log.WriteAsync(strLog);             
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
        }

        private bool IsEmperorExists()
        {
            Process[] prcList = Process.GetProcessesByName("Emperor");
            if (prcList.Length == 0)
            {
                return false;
            }
            _emperor = prcList[0];
            return true;
        }

        private bool IsProcessExists()
        {
            Process[] prcList = Process.GetProcessesByName(_strProcessName);
            if (prcList.Length == 0)
            {
                return false;
            }
            _process = prcList[0];
            return true;
        }

        public void Start()
        {
            if (_thread == null)
            {
                _thread = new Thread(ThreadFun);
                _thread.Start();
                Log.WriteAsync("Start new thread...");
            }          
        }

        public void Stop()
        {
            if (_thread != null)
            {
                _thread.Abort();
                Log.WriteAsync("Abort the thread...");
            }
        }
    }
}
